#include "flowcontrol.h"
#include "ui_flowcontrol.h"
#include "QHelper.h"
#include "serialworker.h"
#include "chart.h"
#include "fileworker.h"
#include "chartview.h"
#include "PSD.h"
#include "mainwindow2.h"
#include "ui_mainwindow2.h"

QT_CHARTS_USE_NAMESPACE

FlowControl::FlowControl(QWidget *parent)
    : QWidget(parent), ui(new Ui::FlowControl)
{
    ui->setupUi(this);

    //调用线程
    threadProcessFlow();
    threadProcessPress();
    threadProcessTemp();
    threadProcessFile();

    /*--------------------图表1---------------------------*/
    chart = new Chart(0,0,1);
    chart->legend()->hide();
    chart->setAnimationOptions(QChart::AllAnimations);
    ChartView *chartView = new ChartView(chart);
    chartView->setRenderHint(QPainter::Antialiasing);
    chart->setTitle("Dynamic Flow Display");
    ui->defectWaveform->grabGesture(Qt::PanGesture);
    ui->defectWaveform->grabGesture(Qt::PinchGesture);
    ui->defectWaveform->setChart(chart);
    connect(this, &FlowControl::chartDataReady,
            chart, &Chart::handleTimeout);

    /*--------------------图表2---------------------------*/
    Chart *chart2 = new Chart(0,0,2);
    chart2->legend()->hide();
    chart2->setAnimationOptions(QChart::AllAnimations);
    ChartView chartView2(chart2);
    chartView2.setRenderHint(QPainter::Antialiasing);
    chart2->setTitle("Dynamic Pressure Display");
    ui->defectWaveform_2->grabGesture(Qt::PanGesture);
    ui->defectWaveform_2->grabGesture(Qt::PinchGesture);
    ui->defectWaveform_2->setChart(chart2);

    connect(this, &FlowControl::chartDataReady2,
            chart2, &Chart::handleTimeout);

    /*--------------------图表3---------------------------*/
    Chart *chart3 = new Chart(0,0,3);
    chart3->legend()->hide();
    chart3->setAnimationOptions(QChart::AllAnimations);
    ChartView chartView3(chart3);
    chartView3.setRenderHint(QPainter::Antialiasing);
    chart3->setTitle("Dynamic Temperature display");
    ui->defectWaveform_3->grabGesture(Qt::PanGesture);
    ui->defectWaveform_3->grabGesture(Qt::PinchGesture);
    ui->defectWaveform_3->setChart(chart3);

    connect(this, &FlowControl::chartDataReady3,
            chart3, &Chart::handleTimeout);

}

FlowControl::~FlowControl()
{
    threadPortFlow.quit();
    threadPortTemp.quit();
    threadPortPressur.quit();
    threadPortFlow.wait();
    threadPortTemp.wait();
    threadPortPressur.wait();
    threadFileWorker.quit();
    threadFileWorker.wait();
    delete ui;
}

/*------------------------------线程处理部分------------------------------*/
void FlowControl::threadProcessFlow()
{
    // 1.新建串口处理程序
    SerialWorker *serilaWorkerFlow = new SerialWorker();
    serilaWorkerFlow -> moveToThread(&threadPortFlow);
    // 2.连接信号和槽
    connect(&threadPortFlow, &QThread::finished,
                serilaWorkerFlow, &QObject::deleteLater);       // 线程结束，自动删除对象
    connect(this, &FlowControl::serialDataSend,
            serilaWorkerFlow, &SerialWorker::doDataSendWork);   // 主线程串口数据发送的信号
    connect(serilaWorkerFlow, &SerialWorker::sendResultToGui,
            this, &FlowControl::handleFlowResults);             // 主线程收到数据结果的信号
    connect(&threadPortFlow, &QThread::started,
            serilaWorkerFlow, &SerialWorker::initSerialPort);   // 初始化线程中的串口
    connect(this, &FlowControl::openFlowPort,
            serilaWorkerFlow, &SerialWorker::openFlow);         // 打开串口
    connect(serilaWorkerFlow, &SerialWorker::openPortSuccess,
            this, &FlowControl::openPortSuccess);               // 串口打开提示
    connect(this, &FlowControl::closeFlowPort,
            serilaWorkerFlow, &SerialWorker::closePort);        // 串口关闭提示
    // 3.开始运行子线程
    threadPortFlow.start();
}

void FlowControl::threadProcessTemp()
{
    SerialWorker *serialWorkerTemp = new SerialWorker();
    serialWorkerTemp -> moveToThread(&threadPortTemp);
    connect(&threadFileWorker, SIGNAL(finished()),
            serialWorkerTemp, SLOT(deleteLater()));             // 自动清除对象
    connect(&threadPortTemp, &QThread::started,
            serialWorkerTemp, &SerialWorker::initSerialPort);   // 初始化串口程序
    connect(this, &FlowControl::openTempPort,
            serialWorkerTemp, &SerialWorker::openTemp);         // 打开温度计的连接并发送指令
    connect(serialWorkerTemp, &SerialWorker::sendResultToTemp,
            this, &FlowControl::handleTempResults);             // 接收温度计返回的数据
    connect(this, &FlowControl::serialDataSendPress,
            serialWorkerTemp, &SerialWorker::doDataSendWork);   // 绑定温度指令数据发送
    connect(serialWorkerTemp, &SerialWorker::openPortSuccess,
            this, &FlowControl::openPortSuccess);               // 串口打开提示
    connect(this, &FlowControl::closeFlowPort,
            serialWorkerTemp, &SerialWorker::closePort);        // 串口关闭提示
    threadPortTemp.start();
}

void FlowControl::threadProcessPress()
{
    SerialWorker *serialWorkerPress = new SerialWorker();
    serialWorkerPress -> moveToThread(&threadPortPressur);

    connect(&threadPortPressur, SIGNAL(finished()),
            serialWorkerPress, SLOT(deleteLater()));            // 自动清除对象
    connect(&threadPortPressur, &QThread::started,
            serialWorkerPress, &SerialWorker::initSerialPort);  // 初始化
    connect(this, &FlowControl::serialDataSendPress,
            serialWorkerPress, &SerialWorker::doDataSendWork);  // 主线程数据发送数据信号
    connect(serialWorkerPress, &SerialWorker::sendResultToPress,
            this, &FlowControl::handlePressResults);            // 主线程接收压力计的结果
    connect(this, &FlowControl::openPressPort,
            serialWorkerPress, &SerialWorker::openPress);       // 打开串口
    connect(serialWorkerPress, &SerialWorker::openPortSuccess,
            this, &FlowControl::openPortSuccess);               // 串口打开提示
    connect(this, &FlowControl::closeFlowPort,
            serialWorkerPress, &SerialWorker::closePort);       // 串口关闭提示
    threadPortPressur.start();
}

void FlowControl::threadProcessFile()
{
    FileWorker *fileWorker = new FileWorker();
    fileWorker -> moveToThread(&threadFileWorker);

    connect(&threadFileWorker, SIGNAL(finished()),
            fileWorker, SLOT(deleteLater()));           //自动清除对象
    connect(&threadFileWorker, &QThread::started,
            fileWorker, &FileWorker::initExcel);        //初始化
    connect(this, &FlowControl::fileDataReady,
            fileWorker, &FileWorker::saveExcelData);    //数据准备好就发送到Excel中
    threadFileWorker.start();
}

/*------------------------------功能函数部分-------------------------------*/

void FlowControl::openPortSuccess()
{
    QMessageBox::about(this, "提示", "打开连接成功！");
}

void FlowControl::closePortSuccess()
{
    QMessageBox::about(this, "提示", "关闭连接成功！");
}

void FlowControl::handleFlowResults(QString result)
{
    ui->textBrowser_2->clear();
    ui->textBrowser_2->append(result);
    // 处理数据
    QStringList resList = result.split(" ");
    double resData;     // 数据：截取返回的流量结果
    QString flow;
    if(resList.size() != 0)
    {
        //进行数据的选择，判断是否稳定
        if (resList.at(1) == ""){
            resData = resList.at(3).toDouble();
            flow = resList.at(3);
        }
        else
        {
            resData = resList.at(1).toDouble();
            flow = resList.at(1);
        }
    }
    else
    {
        resData = 0.0;
        qDebug() << "运行时错误";
    }
    qDebug() << "流量数据" << resData;
    removeEnter(&result);   //对返回结果的换行符处理
    QString press = QString::number(pressData, 'f', 4);     //处理压力数据
    QString temp = QString::number(tempData, 'f', 2);
    // 发射信号
    emit chartDataReady(resData, 1);    //向图表发送数据
    emit fileDataReady(flow, press, temp);      //文件数据接收信号 流量、压力、温度
    emit serialDataSend("ALLR\r\n");            //发送查询数据集
}

void FlowControl::handlePressResults(QString result)
{
    ui->textBrowser_3->clear();
    QString resCut = result.mid(5);
    pressData = resCut.toDouble();
    ui->textBrowser_3->append(result);
    removeEnter(&result);
    qDebug() << "压力值：" << pressData;
    emit chartDataReady2(pressData, 2);
    emit serialDataSendPress("*0100P3\r\n");
}

void FlowControl::handleTempResults(QString result)
{
    // 对result结果进行处理 数据定位、数值转换
    float res = hexToDec(result) / 100;
    qDebug() << "温度数值结果" << res;
    // 设置界面中的温度值
    ui->lcdNumber->display(res);
    // 转换为int类型，设置全局变量
    tempData = res;
    // 调用发送命令
    emit chartDataReady3(tempData,3);
    emit serialDataSendTemp("0103016C000885ED");
}

/*-----------------------槽函数部分------------------------------------------*/
void FlowControl::on_pushButton_clicked()
{
    // 获取选择的流量计串口名称
    QString selectedCOM = ui -> comboBox-> currentText();
    QString str = "ALLR\r\n";
    emit openFlowPort(selectedCOM, str);
}

void FlowControl::on_pushButton_2_clicked()
{
    emit closeFlowPort();
    QMessageBox::about(this, "提示", "连接关闭！");
}

void FlowControl::on_pushButton_12_clicked()
{
    // 获取压力计串口选择
    QString comName = ui -> comboBox_5 -> currentText();
    QString command = "*0100P3\r\n";
    emit openPressPort(comName, command.toLocal8Bit());
}

void FlowControl::on_pushButton_13_clicked()
{
    emit closePressPort();
    QMessageBox::about(this, "提示", "连接关闭！");
}

void FlowControl::on_pushButton_17_clicked()
{
    // 获取温度计串口
    QString comName = ui -> comboBox_7 -> currentText();
    // 查询温度要发送的指令
    QString command = "0103016C000885ED\r\n";
//    qDebug() << "主线程发送指令" << command;
    // 向温度计线程发送信号
    emit openTempPort(comName, command, 1);
}

void FlowControl::on_pushButton_4_clicked()
{
    //调整图表1坐标轴
    chart->m_axisY->setRange(ui->lineEdit->text().toDouble(),ui->lineEdit_2->text().toDouble());
}

void FlowControl::on_pushButton_5_clicked()
{
    //调整图表2坐标轴
     chart->m_axisY->setRange(ui->lineEdit_3->text().toDouble(),ui->lineEdit_4->text().toDouble());
}

void FlowControl::on_pushButton_6_clicked()
{
    //调整图表3坐标轴
     chart->m_axisY->setRange(ui->lineEdit_4->text().toDouble(),ui->lineEdit_5->text().toDouble());
}

void FlowControl::on_pushButton_8_clicked()
{
    QFileDialog *fileDialog = new QFileDialog(this);
    //定义文件对话框标题
    fileDialog->setWindowTitle(tr("打开数据"));
    //设置默认文件路径
    fileDialog->setDirectory(".");
    //设置文件过滤器
    fileDialog->setNameFilter(tr("Date(*.csv *.txt *.xls)"));
    //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles
    fileDialog->setFileMode(QFileDialog::ExistingFiles);
    //设置视图模式
    fileDialog->setViewMode(QFileDialog::Detail);
    //打印所有选择的文件的路径
    if(fileDialog->exec())
    {
        fileNames = fileDialog->selectedFiles()[0];
    }
    for(auto tmp:fileNames)
        qDebug()<<tmp<<endl;
}

void FlowControl::on_pushButton_7_clicked()
{
//    //计算噪声
//    PSD psdinstance = PSD(100000,42,fileNames);
//    QVector<QVector<double>> temp = psdinstance.seepsd();
//    new_win = new MainWindow2();
//    new_win->ui2->plot->addGraph();
//    new_win->ui2->plot->graph(0)->setData(temp[0], temp[1]);
//    new_win->ui2->plot->rescaleAxes(false);
//    new_win->ui2->plot->yAxis->setRange(0,0.05);
//    new_win->ui2->plot->xAxis->setRange(0,100);
//    new_win->show();

}
